﻿namespace CKFinder.Settings
{
    using System;
    using System.Collections;
    using System.Web;

    public class AccessControlManager
    {
        private ArrayList _AclEntries = new ArrayList();
        private Hashtable _ComputedAclEntries = new Hashtable();
        private bool _IsAclEntriesComputed;

        public AccessControl Add()
        {
            AccessControl control = new AccessControl();
            this._AclEntries.Add(control);
            return control;
        }

        private void ComputeAclEntries()
        {
            for (int i = 0; i < this._AclEntries.Count; i++)
            {
                AccessControl control = (AccessControl) this._AclEntries[i];
                string folder = control.Folder;
                string internalKey = control.GetInternalKey();
                int allowedMask = control.GetAllowedMask();
                int deniedMask = control.GetDeniedMask();
                if (this._ComputedAclEntries.ContainsKey(folder))
                {
                    if (((Hashtable) this._ComputedAclEntries[folder]).ContainsKey(internalKey))
                    {
                        int[] numArray = (int[]) ((Hashtable) this._ComputedAclEntries[folder])[internalKey];
                        allowedMask |= numArray[0];
                        deniedMask |= numArray[1];
                    }
                }
                else
                {
                    this._ComputedAclEntries[folder] = new Hashtable(1);
                }
                ((Hashtable) this._ComputedAclEntries[folder])[internalKey] = new int[] { allowedMask, deniedMask };
            }
            this._IsAclEntriesComputed = true;
        }

        public int GetComputedMask(string resourceType, string folderPath)
        {
            if (!this._IsAclEntriesComputed)
            {
                this.ComputeAclEntries();
            }
            int currentMask = 0;
            string userRole = null;
            if (ConfigFile.Current.RoleSessionVar.Length > 0)
            {
                userRole = HttpContext.Current.Session[ConfigFile.Current.RoleSessionVar] as string;
            }
            if ((userRole != null) && (userRole.Length == 0))
            {
                userRole = null;
            }
            folderPath = folderPath.Trim(new char[] { '/' });
            string[] strArray = folderPath.Split(new char[] { '/' });
            string key = "/";
            for (int i = -1; i < strArray.Length; i++)
            {
                if (i >= 0)
                {
                    if (strArray[i].Length == 0)
                    {
                        continue;
                    }
                    if (this._ComputedAclEntries.ContainsKey(key + "*/"))
                    {
                        currentMask = this.MergePathComputedMask(currentMask, resourceType, userRole, key + "*/");
                    }
                    key = key + strArray[i] + "/";
                }
                if (this._ComputedAclEntries.ContainsKey(key))
                {
                    currentMask = this.MergePathComputedMask(currentMask, resourceType, userRole, key);
                }
            }
            return currentMask;
        }

        private int MergePathComputedMask(int currentMask, string resourceType, string userRole, string path)
        {
            Hashtable hashtable = (Hashtable) this._ComputedAclEntries[path];
            string[] strArray = new string[(userRole != null) ? 4 : 2];
            strArray[0] = "*#@#*";
            strArray[1] = "*#@#" + resourceType;
            if (userRole != null)
            {
                strArray[2] = userRole + "#@#*";
                strArray[3] = userRole + "#@#" + resourceType;
            }
            for (int i = 0; i < strArray.Length; i++)
            {
                string key = strArray[i];
                if (hashtable.ContainsKey(key))
                {
                    int[] numArray = (int[]) hashtable[key];
                    currentMask |= numArray[0];
                    currentMask ^= currentMask & numArray[1];
                }
            }
            return currentMask;
        }
    }
}

